package com.topcent.tioxyc.consumer;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.rabbitmq.client.Channel;
import com.topcent.tioxyc.constants.KeyConstant;
import com.topcent.tioxyc.pojo.*;
import com.topcent.tioxyc.pojo.vo.AppVO;
import com.topcent.tioxyc.pojo.vo.ExchangeRateVO;
import com.topcent.tioxyc.util.ApiClient;
import com.topcent.tioxyc.util.ConnmeUtils;
import com.topcent.tioxyc.util.PurchaseCommunity;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 陈百万
 * @date: 2025/4/22 14:28
 * @Description: 费用单_订单费用分摊版
 */
@Component
@RabbitListener(queues = "costOrderAvg")
@Slf4j
public class CostOrderAvgConsumer {
    // 定义允许的总账科目
    private static final Set<String> ALLOWED_ACCOUNTS = Set.of(
            "6601110001", "6601100001", "6601020001", "6601030001",
            "6601080001", "6601130001", "6602170001", "6601070001",
            "6601150001", "6601210001", "6601270001", "6601090001"
    );
    private static final String DATA_UPDATE = "data_update";

    @RabbitHandler
    public void handleMessage(String msg, Channel channel, Message message) throws IOException {
        try {
            // 处理 payload 消息
            log.info("费用单_订单费用分摊版更新的数据Received payload:{}",msg);
            // 在这里处理推送来的数据
            JSONObject payloadJSON = JSONUtil.parseObj(msg);
            String op = payloadJSON.getStr("op");
            String data = payloadJSON.getStr("data");

            // 判断数据部门是否相同
            boolean sameDepartment = isSameDepartment(data);
            if (DATA_UPDATE.equals(op) && sameDepartment) {
                CostOrderAvg costOrderAvg = JSONUtil.toBean(data, CostOrderAvg.class);
                // 逻辑处理，已完成状态
                if(costOrderAvg.getFlowState() == 1 && ("是").equals(costOrderAvg.get_widget_1745218525163())){
                    logicProcess(costOrderAvg);
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("Message acknowledged");
        } catch (Exception e) {
            // 处理异常并拒绝消息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            System.err.println("发送消息失败，重试中 " + e.getMessage());
        }
    }

    // 逻辑处理
    private void logicProcess(CostOrderAvg costOrderAvg) {
        List<CostOrderMoneyAvg.orderCost> orderCostList = new ArrayList<>();
        Header[] headers = ConnmeUtils.createHeaders();
        // 先按部门分组销售订单，提高后续查询效率
        Map<String, List<CostOrderAvg.saleOrder>> saleOrderGroup = costOrderAvg.get_widget_1744883969628().stream()
                .collect(Collectors.groupingBy(saleOrder -> saleOrder.get_widget_1745810687780().getName()));

        for (CostOrderAvg.payInfo info : costOrderAvg.get_widget_1717552286301()) {
            if ("Y".equals(info.get_widget_1745744264223())) {
                String feeDept = info.get_widget_1721461935882(); // 费用归属部门
                List<CostOrderAvg.saleOrder> sameDeptSales = saleOrderGroup.getOrDefault(feeDept, Collections.emptyList());

                if (sameDeptSales.isEmpty()) {
                    log.warn("部门{}下无对应的销售订单", feeDept);
                    continue;
                }

                // 计算部门内销售订单总金额（使用金额RMB）
                BigDecimal totalDeptAmount = sameDeptSales.stream()
                        .map(CostOrderAvg.saleOrder::get_widget_1745218525139)
                        .filter(Objects::nonNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                if (totalDeptAmount.compareTo(BigDecimal.ZERO) == 0) {
                    log.warn("部门{}销售订单总金额为零", feeDept);
                    continue;
                }

                BigDecimal totalPayAmount = info.get_widget_1717568393615(); // 待分摊的本币金额
                BigDecimal remainingDept = totalPayAmount; // 部门级剩余金额，用于最后一个订单平账

                for (int i = 0; i < sameDeptSales.size(); i++) {
                    CostOrderAvg.saleOrder sale = sameDeptSales.get(i);
                    BigDecimal saleAmount = sale.get_widget_1745218525139() != null ?
                            sale.get_widget_1745218525139() : BigDecimal.ZERO;

                    // 计算销售订单占比（保留4位小数）
                    BigDecimal ratio = saleAmount.divide(totalDeptAmount, 10, RoundingMode.HALF_UP);
                    BigDecimal allocatedToSale; // 分配给当前销售订单的金额

                    // 部门级平账：最后一个订单使用剩余金额
                    if (i == sameDeptSales.size() - 1) {
                        allocatedToSale = remainingDept;
                    } else {
                        allocatedToSale = totalPayAmount.multiply(ratio)
                                .setScale(2, RoundingMode.HALF_UP);
                        remainingDept = remainingDept.subtract(allocatedToSale);
                    }

                    // 更新销售订单的金额百分比（保存4位小数）
                    sale.set_widget_1745218525155(ratio.setScale(4, RoundingMode.HALF_UP).doubleValue());

                    // 查询销售单并处理行项分摊
                    List<CostOrderMoneyAvg.orderCost> orderCosts = processSaleOrderLines(sale, allocatedToSale, info, costOrderAvg, headers);
                    if (orderCosts == null) {
                        return;
                    }
                    orderCostList.addAll(orderCosts);
                }
            }
        }
        CostOrderMoneyAvg costOrderMoneyAvg = new CostOrderMoneyAvg();
        costOrderMoneyAvg.set_widget_1746778233868(orderCostList.size());
        costOrderMoneyAvg.set_widget_1746778233848(orderCostList);
        Map<String, Object> parameterInster = new HashMap<>();
        parameterInster.put("app_id", "665fbebb30a77df3f2d3d47d");
        parameterInster.put("entry_id", "6800c3f47187d511daa05013");
        parameterInster.put("is_start_trigger", "true");
        parameterInster.put("data_id", costOrderAvg.get_id());
        costOrderMoneyAvg.set_id(null);
        parameterInster.put("data", ConnmeUtils.convertEntityToMapNull(costOrderMoneyAvg));
        String jsonSalee = JSONUtil.toJsonStr(parameterInster);
        ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/update", headers, jsonSalee);
    }

    /**
     * 处理单个销售订单的行项分摊逻辑（包含行级平账）
     */
    private List<CostOrderMoneyAvg.orderCost> processSaleOrderLines(CostOrderAvg.saleOrder sale, BigDecimal allocatedToSale,
                                       CostOrderAvg.payInfo info, CostOrderAvg costOrderAvg,
                                       Header[] headers) {
        List<CostOrderMoneyAvg.orderCost> orderCosts = new ArrayList<>();
        Map<String, Object> parametereefs = new HashMap<>();
        parametereefs.put("app_id", "667230ad22a8581756b77d52");
        parametereefs.put("entry_id", "669e17aa09cd4f4e279d4d5d");
        HashMap<String, String> communtid = new HashMap<>();
        communtid.put("_widget_1718759603973", sale.get_widget_1745218525115());

        List<SalesOrderKu> salesOrderKuList = PurchaseCommunity.queryBased(parametereefs, headers, communtid, SalesOrderKu.class);
        if (salesOrderKuList.isEmpty()) {
            log.error("销售订单{}查询失败", sale.get_widget_1745218525115());
            return null;
        }

        List<SalesOrderKu.OrderDetail> orderDetails = salesOrderKuList.getFirst().get_widget_1718759603981();
        BigDecimal totalRowAmount = orderDetails.stream()
                .map(ord -> ord.get_widget_1721639369902() != null ?
                        BigDecimal.valueOf(ord.get_widget_1721639369902()) : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        if (totalRowAmount.compareTo(BigDecimal.ZERO) == 0) {
            log.warn("销售订单{}行项总金额为零", sale.get_widget_1745218525115());
            return null;
        }

        BigDecimal rowRemaining = allocatedToSale; // 行级剩余金额，用于最后一个行项平账

        for (int j = 0; j < orderDetails.size(); j++) {
            SalesOrderKu.OrderDetail detail = orderDetails.get(j);
            CostOrderMoneyAvg.orderCost orderMoneyAvg = new CostOrderMoneyAvg.orderCost();
            Double rowAmountDouble = detail.get_widget_1721639369902();
            BigDecimal rowAmount = rowAmountDouble != null ?
                    BigDecimal.valueOf(rowAmountDouble) : BigDecimal.ZERO;

            if (rowAmount.compareTo(BigDecimal.ZERO) == 0) continue; // 跳过金额为0的行项

            BigDecimal rowRatio = rowAmount.divide(totalRowAmount, 10, RoundingMode.HALF_UP);
            BigDecimal allocated;

            // 行级平账：最后一个行项使用剩余金额
            if (j == orderDetails.size() - 1) {
                allocated = rowRemaining;
            } else {
                allocated = allocatedToSale.multiply(rowRatio)
                        .setScale(2, RoundingMode.HALF_UP);
                rowRemaining = rowRemaining.subtract(allocated);
            }

            // 填充分摊明细数据
            orderMoneyAvg.set_widget_1746778233853(rowAmount.setScale(2, RoundingMode.HALF_UP));
            orderMoneyAvg.set_widget_1746778233854(allocated);
            orderMoneyAvg.set_widget_1746778233857(costOrderAvg.get_widget_1721466719214());
            orderMoneyAvg.set_widget_1746778233858(costOrderAvg.get_widget_1717550819156());
            orderMoneyAvg.set_widget_1746778233850(info.get_widget_1721007075246());
            orderMoneyAvg.set_widget_1746778233851(detail.get_widget_1718759603994());
            orderMoneyAvg.set_widget_1746778233852(detail.get_widget_1718759603995());
            orderMoneyAvg.set_widget_1746778233855(info.get_widget_1721461935881());
            orderMoneyAvg.set_widget_1746778233856(info.get_widget_1721461935882()); // 费用归属部门
            orderCosts.add(orderMoneyAvg);
        }
        return orderCosts;
    }

    // 查询汇率
    /*private Double countExchangeRate(){
        Header[] headers = ConnmeUtils.createHeaders();
        // 查询汇率
        Map<String, Object> parametereefs = new HashMap<>();
        parametereefs.put("app_id", "665fbebb30a77df3f2d3d47d");
        parametereefs.put("entry_id", "6660024157715a1b308dcee2");
        parametereefs.put("limit", 100);
        HashMap<String, String> communtid = new HashMap<>();
        communtid.put("_widget_1717568065854", "CNY");communtid.put("_widget_1723450320492", "HKD");
        List<ExchangeRateVO> exchangeRateVOList= PurchaseCommunity.queryBased(parametereefs, headers, communtid, ExchangeRateVO.class);

        // 根据 "_widget_1723450320496" 有效期字段降序排序并取第一个（最近时间）
        ExchangeRateVO latestRate = exchangeRateVOList.stream()
                .filter(item -> item.get_widget_1723450320496() != null).max(Comparator.comparing(ExchangeRateVO::get_widget_1723450320496))
                .orElse(null);

        if (latestRate != null) {
            return latestRate.get_widget_1717568065857();
        }
        return 1.00;
    }*/
    // 判断数据部门是否相同
    private boolean isSameDepartment(String data){
        Header[] headers = ConnmeUtils.createHeaders();
        CostOrderAvg costOrderAvg = JSONUtil.toBean(data, CostOrderAvg.class);
        // 第一次提交
        //if(size == 1){
            List<CostOrderAvg.payInfo> payInfos = costOrderAvg.get_widget_1717552286301();
            List<CostOrderAvg.saleOrder> saleOrders = costOrderAvg.get_widget_1744883969628();

            // 过滤出订单费用分摊科目为 Y 的 payInfo
            List<String> departmentsFromPayInfo = payInfos.stream()
                    .filter(p -> "Y".equalsIgnoreCase(p.get_widget_1745744264223()))
                    .map(CostOrderAvg.payInfo::get_widget_1721461935882)
                    .filter(StrUtil::isNotBlank)
                    .toList();

            // 获取所有销售订单部门
            List<String> departmentsFromSaleOrder = saleOrders.stream()
                    .map(saleOrder -> saleOrder.get_widget_1745810687780().getName())
                    .filter(StrUtil::isNotBlank)
                    .toList();
        log.info("费用单_订单费用分摊版更新的数据Received payload:{}++++{}",departmentsFromPayInfo,departmentsFromSaleOrder);
        // 检查是否每个费用归属部门都能在销售订单部门中找到（包含关系）
        boolean allMatched = new HashSet<>(departmentsFromSaleOrder).containsAll(departmentsFromPayInfo);
        // 检查销售订单部门是否有额外的不匹配部门
        boolean noExtraDepartments = new HashSet<>(departmentsFromPayInfo).containsAll(departmentsFromSaleOrder);

        // 检查是否每个费用归属部门都能在销售订单部门中找到（包含关系）
        log.info("检查是否每个费用归属部门都能在销售订单部门中找到（包含关系）{}44444{}", allMatched, noExtraDepartments);
        if (allMatched && noExtraDepartments) {
            log.info("完全匹配");
        }else {
            AppVO vo = new AppVO();
            Map<String, Object> parameterInster = new HashMap<>();
            parameterInster.put("app_id", "665fbebb30a77df3f2d3d47d");
            parameterInster.put("entry_id", "6800c3f47187d511daa05013");
            parameterInster.put("is_start_trigger", "true");
            parameterInster.put("data_id", costOrderAvg.get_id());
            vo.set_id(null);
            vo.set_widget_1745805221542("Y");
            parameterInster.put("data", ConnmeUtils.convertEntityToMapNull(vo));
            String jsonSalee = JSONUtil.toJsonStr(parameterInster);
            log.info("更新的数据Y{}", jsonSalee);
            ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/update", headers, jsonSalee);
            return false;
        }
        return true;
    }
}
